package com.cdks.wuxiu.api.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.json.JSONObject;
import com.cdks.wuxiu.api.component.aliyun.AliyunConfig;
import com.cdks.wuxiu.api.component.constant.Constant;
import com.cdks.wuxiu.api.model.common.AuthParam;
import com.cdks.wuxiu.api.model.common.CommonParam;
import com.cdks.wuxiu.api.model.dto.CloudStorageDTO;
import com.cdks.wuxiu.api.model.param.SystemExploreParam;
import com.cdks.wuxiu.api.model.param.SystemFeedbackParam;
import com.cdks.wuxiu.api.model.param.SystemGetParam;
import com.cdks.wuxiu.api.model.param.SystemGetSmsCodeParam;
import com.cdks.wuxiu.api.model.param.SystemHomeParam;
import com.cdks.wuxiu.api.model.param.SystemSetPushInfoParam;
import com.cdks.wuxiu.api.model.vo.AppBannerInfoVO;
import com.cdks.wuxiu.api.model.vo.AppVersionInfoVO;
import com.cdks.wuxiu.api.model.vo.SystemGetParamVO;
import com.cdks.wuxiu.api.model.vo.SystemHomeVO;
import com.cdks.wuxiu.api.model.vo.SystemMineVO;
import com.cdks.wuxiu.api.service.AccountService;
import com.cdks.wuxiu.api.service.AuthService;
import com.cdks.wuxiu.api.service.CommonService;
import com.cdks.wuxiu.api.service.SystemService;
import com.cdks.wuxiu.api.service.UserService;
import com.cdks.wuxiu.api.service.VideoService;
import com.cdks.wuxiu.api.service.VoiceService;
import com.cdks.wuxiu.api.util.TimeUtils;
import com.cdks.wuxiu.common.component.constant.ApiCodeEnum;
import com.cdks.wuxiu.common.exception.ApiException;
import com.cdks.wuxiu.common.model.api.ApiResult;
import com.cdks.wuxiu.entity.mysql.AppBannerConfig;
import com.cdks.wuxiu.entity.mysql.AppVersionConfig;
import com.cdks.wuxiu.entity.mysql.BannedUserInfo;
import com.cdks.wuxiu.entity.mysql.FeedbackInfo;
import com.cdks.wuxiu.entity.mysql.UserBaseInfo;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;
import javax.annotation.Resource;
import javax.validation.Valid;


@Slf4j
@Api(tags = "系统接口")
@RestController
@RequestMapping("/system")
public class SystemController {
    @Resource
    private AuthService authService;
    @Resource
    private AccountService accountService;     
    @Resource
    private CommonService commonService;
    @Resource
    private SystemService systemService;
    @Resource
    private UserService userService;
    @Resource
    private VideoService videoService;
    @Resource
    private VoiceService voiceService;    


    @ApiOperation("获取参数配置")
    @PostMapping("/getParams")
    public ApiResult<SystemGetParamVO> getParams(@RequestBody @Valid SystemGetParam param) {
        SystemGetParamVO vo  = new SystemGetParamVO();

        SystemGetParamVO.CloudStorageParam ossParam  = new SystemGetParamVO.CloudStorageParam();
        ossParam.setUrlPath(AliyunConfig.CLOUD_URL_PATH);
        //用户登录后需要校验 token
        if ((param.getUserId() != null) && (param.getToken() != null))
        {
            CloudStorageDTO ossData  = authService.getOssAuthData();
            if (ossData != null)
            {
                BeanUtil.copyProperties(ossData, ossParam);
            }

            ossParam.setBucket(AliyunConfig.CLOUD_BUCKET_NAME);
            ossParam.setEndPoint(AliyunConfig.CLOUD_END_POINT);

            vo.setKmsgParam(authService.getKmsgData(param.getUserId()));

            SystemGetParamVO.SystemParam sysParam  = new SystemGetParamVO.SystemParam();
            BeanUtil.copyProperties(systemService.getSystemParams(), sysParam);
            vo.setSysParam(sysParam);
        }

        vo.setOssParam(ossParam);
        
        return ApiResult.success(vo);
    }

    @ApiOperation("获取短信验证码")
    @PostMapping("/getSmsCode")
    public ApiResult<Object> getSmsCode(@RequestBody @Valid SystemGetSmsCodeParam param) {
        String phone  = param.getPhone();
        //检查验证码获取次数
        commonService.checkSmsCount(phone);
        
        BannedUserInfo info  = accountService.checkAccount(param.getUdid(), phone);
        if (info != null)
        {
            log.info("checkAccount: " + info);
            
            //永久封禁
            if (info.getExpire() == 0)
            {
                throw new ApiException(10, "您的账号因" + info.getReason() + "已被封禁，若有疑问请咨询官方微信：xinsuwx");
            }

            //解封时间未到
            if (info.getExpire() > TimeUtils.getTimeSecond())
            {
                throw new ApiException(10, "您的账号因" + info.getReason() + "已被封禁，" + TimeUtils.getLocalDateTime("yyyy-MM-dd HH:mm:ss", info.getExpire()) + " 前不可使用。若有疑问请咨询官方微信：xinsuwx");
            }

            throw new ApiException(10, "禁止注册，若有疑问请咨询官方微信：xinsuwx");
        }
  
        // 生成验证码
        // 非用户账号使用固定验证码
        String smsCode;
        UserBaseInfo userInfo  = userService.getUserByPhone(phone);
        if ((userInfo != null) && (userInfo.getType() != Constant.ACCOUNT_TYPE_USER))
        {
            smsCode  = "000000";
        }
        else
        {
            smsCode  = String.valueOf(RandomUtil.randomInt(100000, 999999));
        }

        //发送验证码
        commonService.sendSmsCode(phone, smsCode);

        return ApiResult.success("验证码已发送，十分钟内有效。请注意接收。");
    }

    @ApiOperation("获取最新版本")
    @PostMapping("/getLastVersion")
    public ApiResult<AppVersionInfoVO> getLastVersion(@RequestBody @Valid CommonParam param) {
        AppVersionConfig appVersionConfig = systemService.getVersionByBranch(param.getBranch());
        if (appVersionConfig != null) {
            return ApiResult.success(BeanUtil.copyProperties(appVersionConfig, AppVersionInfoVO.class));
        }

        return ApiResult.success();
    }

    @ApiOperation("获取banner")
    @PostMapping("/getBanner")
    public ApiResult<Object> getBanner(@RequestBody @Valid CommonParam param) {
        List<AppBannerConfig> bannerList  = systemService.getBannerByPlat(param.getBranch() / 100);
        List<AppBannerInfoVO> retVOList  = new ArrayList<>();

        for (AppBannerConfig config : bannerList) {
            retVOList.add(BeanUtil.copyProperties(config, AppBannerInfoVO.class));
        }

        JSONObject json  = new JSONObject();
        json.set("bannerList", retVOList);

        return ApiResult.success(json);
    }

    @ApiOperation("获取“首页”显示数据")
    @PostMapping("/home")
    public ApiResult<Object> home(@RequestBody @Valid SystemHomeParam param) {
        UserBaseInfo userInfo  = param.getUserInfo();
        long userId  = (userInfo == null) ? 0 : userInfo.getUserId();
        int sex = (userInfo == null) ? 2 : 3 - userInfo.getSex();
        SystemHomeVO vo  = new SystemHomeVO();

        if (userInfo == null)
        {
            if (param.getCount() > 0) {
                JSONObject json  = new JSONObject();
                json.set("scheme", "xinsu://account/login");
                
                return ApiResult.failed(11, "查看更多精彩内容，请先登录", json);  
            }
        }

        vo.setVideoList(videoService.getPlayList(userId, sex));
        vo.setVoiceList(voiceService.getPlayList(userId, sex));

        return ApiResult.success(vo);
    }

    @ApiOperation("获取“发现”显示数据")
    @PostMapping("/explore")
    public ApiResult<Object> explore(@RequestBody @Valid SystemExploreParam param) {
        //未登录只能查看前三页
        if (param.getPage() >= 3)
        {
            if ((param.getUserId() == null) || (param.getToken() == null))
            {
                return ApiResult.failed(ApiCodeEnum.NEED_LOGIN);
            }
        }

        UserBaseInfo userInfo  = param.getUserInfo();        
        long userId  = 0;
        int sex      = 2; // 默认显示女性
        int role     = 3; // 默认显示已认证
        int userType = Constant.ACCOUNT_TYPE_TEST;
        if (userInfo != null)
        {
            userId    = param.getUserId();
            sex       = 3 - userInfo.getSex();
            role      = 3 - userInfo.getAuthRole();
            userType  = userInfo.getType();
        }

        JSONObject json  = new JSONObject();
        json.set("userList", userService.getUserList(userId, sex, role, userType, param.getType(), param.getPage()));

        return ApiResult.success(json);
    }

    @ApiOperation("获取“我的”显示数据")
    @PostMapping("/mine")
    public ApiResult<SystemMineVO> mine(@RequestBody @Valid AuthParam param) {
        SystemMineVO vo  = new SystemMineVO();

        //获取用户信息
        UserBaseInfo userInfo  = param.getUserInfo();
        //设置待审昵称
        if ((userInfo.getInfoStatus() & Constant.INFO_STATUS_NAME) > 0)
        {
            userInfo.setNickName(userService.getAuditNickname(param.getUserId()));
        }

        //设置待审头像
        if ((userInfo.getInfoStatus() & Constant.INFO_STATUS_HEAD) > 0)
        {
            userInfo.setHeadUri(userService.getAuditPortrait(param.getUserId()));
        }

        vo.setUserInfo(userInfo);

        //获取版本信息
        AppVersionConfig appVersionConfig = systemService.getVersionByBranch(param.getBranch());
        if (appVersionConfig != null) {
            vo.setVersion(BeanUtil.copyProperties(appVersionConfig, AppVersionInfoVO.class));
        }

        return ApiResult.success(vo);
    }

    @ApiOperation("意见反馈")
    @PostMapping("/feedback")
    public ApiResult<Object> feedback(@RequestBody @Valid SystemFeedbackParam param) {
        FeedbackInfo feed  = new FeedbackInfo();
        BeanUtil.copyProperties(param, feed);

        feed.setCreateTime(TimeUtils.getTimeSecond());
        systemService.saveFeedBack(feed);

        return ApiResult.success();
    }

    @ApiOperation("设置推送信息")
    @PostMapping("/setPushInfo")
    public ApiResult<Object> setPushInfo(@RequestBody @Valid SystemSetPushInfoParam param) {
        userService.updatePushInfo(param.getUserId(), param.getPushToken(), param.getPushStatus());

        return ApiResult.success();
    }

    @ApiOperation("设置设备信息")
    @PostMapping("/setDeviceInfo")
    public ApiResult<Object> setDeviceInfo(@RequestBody @Valid AuthParam param) {
        accountService.updateDeviceInfo(param.getUserId(), param.getUdid());

        return ApiResult.success();
    }
}

